package com.enterprise.projectManager.resource;

import com.enterprise.projectManager.component.UploadProperties;
import com.enterprise.projectManager.model.Appendix;
import com.enterprise.projectManager.model.Response;
import com.enterprise.projectManager.rope.AppendixRope;
import com.enterprise.projectManager.service.implemention.AppendixImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static java.time.LocalDateTime.now;
import static java.util.Map.of;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.OK;

@RestController
@RequiredArgsConstructor
@RequestMapping("/crebas/appendix")
@Slf4j
public class AppendixResource {
    private final AppendixImpl appendixService;
    private final AppendixRope appendixRope;
    private final UploadProperties uploadProperties;
    @PostMapping("/upload")
    public ResponseEntity<Response> handleFileUpload(
            @RequestParam("files") List<MultipartFile> files, @RequestParam("projectId") String projectId) {
        return ResponseEntity.ok(
                Response.builder()
                        .timeStamp(now())
                        .data(of("uploadFile",appendixService.uploadToLocal(files,projectId)))
                        .message("上传附件")
                        .status(CREATED)
                        .statusCode(CREATED.value())
                        .build()
        );
    }
//    @PostMapping("/upload2")
//    public String handleFileUpload(@RequestParam("files") List<MultipartFile> files,
//                                   @RequestParam("projectId") String projectId) {
//        if (files.isEmpty()) {
//            return "请选择一个文件上传";
//        }
//
//        for (MultipartFile file : files) {
//            if (!file.isEmpty()) {
//                try {
//                    // 创建文件保存路径
//                    String fileName = file.getOriginalFilename();
//                    String filePath = "src/main/resources/uploads/" + projectId + "/" + fileName;
//
//                    // 创建目录
//                    File dir = new File("src/main/resources/uploads/" + projectId);
//                    if (!dir.exists()) {
//                        dir.mkdirs();
//                    }
//
//                    // 保存文件
//                    byte[] bytes = file.getBytes();
//                    Path path = Paths.get(filePath);
//                    Files.write(path, bytes);
//
//                } catch (Exception e) {
//                    return "上传失败：" + e.getMessage();
//                }
//            } else {
//                return "上传失败，请选择文件";
//            }
//        }
//
//        return "上传成功";
//    }
    @GetMapping("/getDownloadUrl/{projectId}")
    public ResponseEntity<Response> getDownloadUrl(@PathVariable String projectId){
        return ResponseEntity.ok(
                Response.builder()
                        .timeStamp(now())
                        .data(of("file",appendixService.getDownloadUrl(projectId)))
                        .message("下载附件")
                        .status(CREATED)
                        .statusCode(CREATED.value())
                        .build()
        );
    }
    @GetMapping("/download/{projectId}")
    public ResponseEntity<Resource> downloadFile(@PathVariable String projectId) throws IOException {
        String projectPath = uploadProperties.getDirectory()+projectId;
        List<Resource> resources =new ArrayList<>();
        try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(projectPath))) {
            for (Path path : directoryStream) {
                System.out.println(path.getFileName());
                System.out.println(path);
                Resource resource = new UrlResource(path.toUri());
                resources.add(resource);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", resources.get(0).getFilename());

        // 返回文件作为响应
        return ResponseEntity.ok()
                .headers(headers)
                .body(resources.get(0));
    }

    @PostMapping("/downloadOneFile")
    public ResponseEntity<Resource> downloadOneFile(@RequestParam String appendixId) throws IOException {
        Appendix appendix = appendixRope.findByAppendixId(appendixId);
        System.out.println(appendix.getAppendixName());
        if (appendix == null) return ResponseEntity.notFound().build();
        String filePath = appendix.getAppendixPath();
        // 从文件路径中获取文件资源
        FileSystemResource resource = new FileSystemResource(filePath);
        if (!resource.exists()) {
            return ResponseEntity.notFound().build();
        }

        // 获取文件名
        String filename = resource.getFilename();
        if (filename == null || filename.isEmpty()) {
            return ResponseEntity.badRequest().build();
        }
        // 设置HTTP响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"");
        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);

        return ResponseEntity.ok()
                .headers(headers)
                .body(resource);
    }

    @GetMapping("/getFileList/{projectId}")
    public ResponseEntity<Response> listFiles(@PathVariable String projectId){
        return ResponseEntity.ok(
                Response.builder()
                        .timeStamp(now())
                        .data(of("fileList",appendixService.getProjectFileList(projectId)))
                        .message("项目"+projectId+"的附件列表")
                        .status(OK)
                        .statusCode(OK.value())
                        .build()
        );
    }

    //下载项目文件夹的所有文件
    @GetMapping("/downloadZIP/{projectId}")
    public ResponseEntity<Resource> downloadZIPFiles(@PathVariable String projectId) {
        String projectPath = uploadProperties.getDirectory() + projectId;
        Path projectDir = Paths.get(projectPath);

        // 验证路径是否安全
        if (!projectDir.startsWith(uploadProperties.getDirectory())) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        }
        // 检查目录是否存在并且是一个目录
        if (!Files.exists(projectDir) || !Files.isDirectory(projectDir)) {
            // 文件夹为空，返回相应的响应
            return ResponseEntity.ok()
                    .body(null);
        }

        // 尝试列出目录内容
        long count = 0;
        try {
            count = Files.list(projectDir).count();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (count == 0) {
            // 文件夹为空，返回相应的响应
            return ResponseEntity.ok()
                    .body(null);
        }
        // 创建ZIP文件来存储所有文件
        String zipFilename = projectId+"Files.zip";
        Path zipFilePath = Paths.get(uploadProperties.getDirectory() + zipFilename);
        try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(zipFilePath))) {
            Files.walk(projectDir)
                    .filter(path -> !Files.isDirectory(path))
                    .forEach(path -> {
                        ZipEntry zipEntry = new ZipEntry(projectDir.relativize(path).toString());
                        try {
                            zs.putNextEntry(zipEntry);
                            Files.copy(path, zs);
                            zs.closeEntry();
                        } catch (IOException e) {
                            System.err.println(e);
                        }
                    });
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }

        // 加载ZIP文件作为资源
        Resource resource = null;
        try {
            resource = new UrlResource(zipFilePath.toUri());
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
        String encodedFilename = null;
        try {
            encodedFilename = URLEncoder.encode(resource.getFilename(), StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", encodedFilename);

        return ResponseEntity.ok()
                .headers(headers)
                .body(resource);
    }

}
